//
//  CategoryViewController.m
//  CS Inventory Manager
//
//  Created by Ian Smith on 2/25/13.
//  Copyright (c) 2013 Transylvania University. All rights reserved.
//

#import "CategoryViewController.h"
#import "TypeViewController.h"
#import "Category.h"
#import "Type.h"
#import "Item.h"
#import "EditCategoryViewController.h"
#import "AppDelegate.h"
#import "CheckoutRecordPatron.h"

@interface CategoryViewController () {
    
    NSMutableArray *categories;
    
    /* xml */
	NSURL* url;
	NSMutableData* requestData;
	NSMutableString* theData;
	NSXMLParser* fileParser;
	Category *tempCat;
    Type *tempType;
    Item *tempItem;
    CheckoutRecord *tempCheckout;
    CheckoutRecordPatron *tempPatron;
	BOOL noNetwork;
    Category *addNew;
    
    UIBarButtonItem *searchButton;
}
@end

@implementation CategoryViewController
@synthesize loginDisplayed,detailViewController;

-(BOOL)refreshXML:(id)sender{
    
    self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refreshing data..."];
    
    noNetwork = NO;
	[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    
    // drop the categories array (also drop it from AppDelegate)
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    appDelegate.categories = nil;
    categories = nil;
	categories = [[NSMutableArray alloc] init];
    appDelegate.categories = categories;
    
    // get data from internet
    url = [[NSURL alloc] initWithString:@"http://www.cs.transy.edu/zoellers/inventory/getItems.php?secret=pass"];
	NSURLRequest *dataRequest = [NSURLRequest requestWithURL:url
												 cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
											 timeoutInterval:60];
	NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:dataRequest delegate:self];
	if (connection) {
		NSLog(@"refreshXML: Created connection request.");
        
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"MMM d, h:mm a"];
        NSString *lastUpdated = [NSString stringWithFormat:@"Last updated on %@",[formatter stringFromDate:[NSDate date]]];
        self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:lastUpdated];
        [self.refreshControl endRefreshing];
        
        return true;
	}
	else {
		NSLog(@"refreshXML: ERROR: Could not create connection request.");
		//Output no internet
        return false;
	}
	
}

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
    
    }
    return self;
}

-(void) awakeFromNib
{
    self.navigationItem.rightBarButtonItem = self.editButtonItem;
    self.tableView.allowsSelectionDuringEditing = YES;
    
    [super awakeFromNib];
    [self refreshXML:nil];
}

-(void)viewDidAppear:(BOOL)animated
{

    [self.tableView reloadData];
    
    // this may not be the best way to do this, but viewDidLoad is "too soon"
    if (!loginDisplayed) {
        // show the login view controller
        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        
        [[appDelegate loginViewController] setModalPresentationStyle:UIModalPresentationFormSheet];
        [[appDelegate loginViewController] setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
        [[appDelegate loginViewController] setDelegate:self];
        [self presentViewController:[appDelegate loginViewController] animated:YES completion:nil];
        [self setLoginDisplayed:YES];
    }

}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.clearsSelectionOnViewWillAppear = NO;
    
    // allow pull down for refresh
    UIRefreshControl *refresh = [[UIRefreshControl alloc] init];
    refresh.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to Refresh"];
    [refresh addTarget:self action:@selector(refreshXML:) forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refresh;
    
    self.detailViewController = (ItemDetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
    
    // if scanning is support, initialize it to save time later
    [self initScanSearchFeature];
    if (RL_CheckReadyStatus()) {
        
    } else {
        self.navigationItem.leftBarButtonItem = nil;
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return categories.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    
    cell.textLabel.text = [categories[indexPath.row] name];
    
    NSLog(@"Cell generation being called!");
    
    return cell;
}

-(void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    [super setEditing:editing animated:animated];
    if (editing) {
        searchButton = self.navigationItem.leftBarButtonItem; // save the old one
        self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addItem:)];
    } else {
        if (!RL_CheckReadyStatus()) {
            // bar scan not supported
            self.navigationItem.leftBarButtonItem = nil;
        } else {
            self.navigationItem.leftBarButtonItem = searchButton;
        }
    
    }
}

//Function that responds to a tap on the "Add" button while in editing view
-(void)addItem:sender {
    addNew = [[Category alloc] init];
    [addNew setCatId:0];
    [self performSegueWithIdentifier:@"editCategory" sender:addNew];
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/


- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // make the web call to delete
        // set all params for URL
        NSString *uid = [NSString stringWithFormat:@"%d", [[categories objectAtIndex:indexPath.row] catId]];
        
        // generate the URL and use %20 encoding
        NSString *urlStr = [NSString stringWithFormat:@"http://www.cs.transy.edu/zoellers/inventory/category.php?secret=pass&id=%@",uid];
        NSString *final = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        
        NSLog(@"The url is: >>>>>%@<<<<<", final);
        
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:final]];
        
        // make web request and catch error
        NSError * e;
        NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&e];
        
        // log the value returned from the web server
        NSString *value = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"return from web: %@", value);
        //Delete locally as well
        [categories removeObjectAtIndex:indexPath.row];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }    
}

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

#pragma mark - Table view delegate
//Prepares for the calling of the manual segue that drives the drill-down interface
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqual: @"Segue"]) {
        //Grab the next view controller so we can alter some properties before it appears
        //  in order to pass on what category the user clicked on
        TypeViewController *nextController = segue.destinationViewController;
        //Set the title of the next table view to the category the user clicked on. This is
        //  typical of drill-down interfaces and also gives us an easy string to reference to see
        //  what category we are looking at while down in Type view
        nextController.category = sender;
        [nextController prepareViewController];
        NSLog(@"prepareForSegue in CategoryViewController: ID#: %i",[sender catId]);
    }
    else if ([segue.identifier isEqual: @"editCategory"]) {
        EditCategoryViewController *nextController = segue.destinationViewController;
        nextController.theCategory = sender;
        [nextController setDelegate:self];
    }
}

//Edited to call the manual segue I set up in storyboard
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.tableView.editing == YES) {
        Category *object = categories[indexPath.row];
        [self performSegueWithIdentifier:@"editCategory" sender:object];
    }
    else {
        Category *object = categories[indexPath.row];
        NSLog(@"didSelectRowAtIndexPath ID#: %i",[object catId]);
        //Call the segue, and pass the category that was selected along as the sender
        [self performSegueWithIdentifier:@"Segue" sender:object];
    }
}

- (void) initScanSearchFeature {
    
    pickerController = [[BarcodePickerController alloc] init];
    [pickerController setDelegate:self];
    
    [pickerController prepareToScan];
    NSLog(@"RedLaser init Status: %d",RL_CheckReadyStatus());
	// Make ourselves an overlay controller and tell the SDK about it.
	OverlayController *overlayController = [[OverlayController alloc] init];
	[pickerController setOverlay:overlayController];
    
}

- (IBAction) scanButtonPressed {
    NSLog(@"RedLaser scan Status: %d",RL_CheckReadyStatus());

    // pop up the scan view
    [pickerController setModalPresentationStyle:UIModalPresentationFormSheet];
    [pickerController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
    [self presentViewController:pickerController animated:YES completion:nil];
    
}

- (void) barcodePickerController:(BarcodePickerController*)picker returnResults:(NSSet *)results
{
	
	// Restore main screen (and restore title bar for 3.0)
	[self dismissViewControllerAnimated:YES completion:NULL];
	
	// If there's any results, save them in our scan history
	if (results && [results count]) {
		NSMutableDictionary *scanSession = [[NSMutableDictionary alloc] init];
		[scanSession setObject:[NSDate date] forKey:@"Session End Time"];
		[scanSession setObject:[results allObjects] forKey:@"Scanned Items"];
        
        BarcodeResult *barcode = [[scanSession objectForKey:@"Scanned Items"] objectAtIndex:0];
        
        NSLog(@"Barscan found barcode: %@",barcode.barcodeString);
        
        // search for result
        AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
        for (int i = 0; i < appDelegate.categories.count; i++) {
            Category *category = appDelegate.categories[i];
            for (int j = 0; j < category.types.count; j++) {
                Type *type = category.types[j];
                for (int k = 0; k < type.items.count; k++) {
                    Item *item = type.items[k];
                    if ([[item assetId] isEqualToString:barcode.barcodeString]) {
                        
                        // found a match, put it in the DVC and stop the search!
                        self.detailViewController.detailItem = item;

                       return;
                    }
                }
            }
        }
        
        NSString *message = [NSString stringWithFormat:@"Asset ID# '%@' was not found in the database. Please check to make sure the item you're looking for has been added correctly.",barcode.barcodeString];
        
        // was not able to match barcode with inventory
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Item not found!" message:message delegate:self cancelButtonTitle:@"Dismiss"  otherButtonTitles:nil, nil];
        [alert show];
        alert = nil;
        
    }
}

/********************************************************************
 for xml parsing
 ********************************************************************/

//connection finished loading it's data
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
	// DEBUGGING: NSLog(@"GRABBED DATA%@", requestData);
    if (requestData) {
        NSLog(@"connectionDidFinishLoading: Retrieved XML data. Beginning XML parsing process.");
    } else {
        NSLog(@"connectionDidFinishLoading: ERROR: No XML data retrieved.");
    }
	//allocate file parser
	fileParser = [[NSXMLParser alloc] initWithData:requestData];
	
	//set current object as delegate
	[fileParser setDelegate:self];
	//start parsing
	[fileParser parse];
    
    NSLog(@"connectionDidFinishLoading: Ending XML parsing process");
    fileParser = nil;
}


//Connection failed
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"\t\tconnection DidFailWithError: ERROR: Connection failed, trigger notification.");
	//Connection failed, tell the user
	UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Unable to connect." message:@"Your device is unable to connect to the network. Please check your network connection and try again." delegate:self cancelButtonTitle:@"Dismiss"  otherButtonTitles:nil, nil];
	[alert show];
	alert = nil;
	noNetwork = YES;
	[self.tableView reloadData];
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
	
}
//Connection Started
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
	//allocate a place to store the data until it is whole
	requestData = [[NSMutableData alloc] init];
	[requestData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
	//Append data
	[requestData appendData:data];
}
//Found start tag
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
	if ([elementName isEqual:@"xml"]) {
		//Allocate a string that will hold the data
		theData = [[NSMutableString alloc] init];
	}
	else if ([elementName isEqual:@"category"]) {
		//allocate a temporary variable to hold the data until it is ready to be stored in the array
		tempCat = [[Category alloc] init];
	} else if ([elementName isEqual:@"type"]) {
        // allocate a temp type
        tempType = [[Type alloc] init];
    } else if ([elementName isEqual:@"item"]) {
        // allocate a temp item
        tempItem = [[Item alloc] init];
    } else if ([elementName isEqual:@"checkout"]) {
        // allocate a checkout
        tempCheckout = [[CheckoutRecord alloc] init];
        tempCheckout.patrons = [[NSMutableArray alloc] init];
    } else if ([elementName isEqual:@"copatron"]) {
        // allocate a new checkout patron
        tempPatron = [[CheckoutRecordPatron alloc] init];
    }
    
	if (![elementName isEqual:@"xml"]) {
		//black the string
		[theData setString:@""];
	}
}
//Found end tag while parsing
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
	//Check the end element name and store it in theData to the appropriate variable
	if ([elementName isEqual:@"xml"]) {
        
	} else if ([elementName isEqual:@"cat_name"]) {
		[tempCat setName:[[NSString alloc] initWithString:theData]];
	} else if ([elementName isEqual:@"cat_id"]) {
		[tempCat setCatId:[theData intValue]];
	} else if ([elementName isEqual:@"type_id"]) {
        [tempType setTypeId:[theData intValue]];
    } else if ([elementName isEqual:@"type_name"]) {
        [tempType setName:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"type_manufact"]) {
        [tempType setManufacturer:[[NSString alloc] initWithString:theData]];
	} else if ([elementName isEqual:@"mod_id"]) {
        [tempItem setMid:[theData intValue]];
    } else if ([elementName isEqual:@"mod_name"]) {
		[tempItem setModel:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"item_id"]) {
		[tempItem setItemId:[theData intValue]];
    } else if ([elementName isEqual:@"item_serial"]) {
		[tempItem setSerialNo:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"item_assetno"]) {
        [tempItem setAssetId:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"item_cost"]) {
        [tempItem setCost:[theData doubleValue]];
    } else if ([elementName isEqual:@"item_value"]) {
		[tempItem setItemValue:[theData doubleValue]];
    } else if ([elementName isEqual:@"item_added"]) {
        NSString *dateString = [[NSString alloc] initWithString:theData];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        // this is imporant - we set our input date format to match our input string
        // if format doesn't match you'll get nil from your string, so be careful
        [dateFormatter setDateFormat:@"yyyy-MM-dd"];
        // voila!
		[tempItem setDateAdded:[dateFormatter dateFromString:dateString]];
    } else if ([elementName isEqual:@"item_status_id"]) {
        [tempItem setStatusId:[theData intValue]];
    } else if ([elementName isEqual:@"item_status_name"]) {
        [tempItem setStatus:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"item_notes"]) {
		[tempItem setNotes:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"item_location"]) {
        [tempItem setLocation:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"checkoutID"]) {
        [tempCheckout setCheckoutID:[theData intValue]];
    } else if ([elementName isEqual:@"itemType"]) {
        [tempCheckout setItemType:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"itemModel"]) {
            [tempCheckout setItemModel:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"itemAssetID"]) {
            [tempCheckout setAssetNo:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"patronName"]) {
            [tempPatron setName:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"patronEmail"]) {
            [tempPatron setEmail:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"patronId"]) {
            [tempPatron setId:[theData intValue]];
    } else if ([elementName isEqual:@"outDate"]) {
        NSString *dateString = [[NSString alloc] initWithString:theData];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        // this is imporant - we set our input date format to match our input string
        // if format doesn't match you'll get nil from your string, so be careful
        [dateFormatter setDateFormat:@"yyyy-MM-dd"];
        // voila!
        [tempCheckout setOutDate:[dateFormatter dateFromString:dateString]];
    } else if ([elementName isEqual:@"dueDate"]) {
        NSString *dateString = [[NSString alloc] initWithString:theData];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        // this is imporant - we set our input date format to match our input string
        // if format doesn't match you'll get nil from your string, so be careful
        [dateFormatter setDateFormat:@"yyyy-MM-dd"];
        // voila!
        [tempCheckout setDueDate:[dateFormatter dateFromString:dateString]];
    } else if ([elementName isEqual:@"returnDate"]) {
        NSString *dateString = [[NSString alloc] initWithString:theData];
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        // this is imporant - we set our input date format to match our input string
        // if format doesn't match you'll get nil from your string, so be careful
        [dateFormatter setDateFormat:@"yyyy-MM-dd"];
        // voila!
        [tempCheckout setInDate:[dateFormatter dateFromString:dateString]];
    } else if ([elementName isEqual:@"outNotes"]) {
        [tempCheckout setOutNotes:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"inNotes"]) {
        [tempCheckout setInNotes:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"profName"]) {
        [tempCheckout setProfName:[[NSString alloc] initWithString:theData]];
    } else if ([elementName isEqual:@"checkout"]) {
        [tempItem setCheckoutActive:tempCheckout];
        tempCheckout = nil;
    } else if ([elementName isEqual:@"item"]) {
        [[tempType items] addObject:tempItem];
        [tempItem setMyType:tempType];
        tempItem = nil;
    } else if ([elementName isEqual:@"type"]) {
        [[tempCat types] addObject:tempType];
        [tempType setMyCategory:tempCat];
        tempType = nil;
    } else if ([elementName isEqual:@"copatron"]) {
        // add the temp patron to the array of patrons
        [[tempCheckout patrons] addObject:tempPatron];
        NSLog(@"total patrons found for CO %d",[[tempCheckout patrons] count]);
        tempPatron = nil;
    } else if ([elementName isEqual:@"category"]) {
		[categories addObject:tempCat];
		tempCat = nil;
    }
	
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
	[theData appendString:string];
}

- (void)parserDidEndDocument:(NSXMLParser *)parse
{
	[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    NSLog(@"\t\tparserDidEndDocument: Data retrieved, reloading table.");
	[self.tableView reloadData];
}

@end